import type { IFunction, IObject } from '@/types/interface';

/**
 * 获取对象下的字段值
 * @param record 对象
 * @param key 字段路径，如 'a.b.c'
 * @param defaultValue 默认值
 * @returns 字段值
 */
export function getValueByKeys(record: IObject = {}, key: string, defaultValue?: unknown): any {
  const keys = key.split('.');
  for (let i = 0; i < keys.length; i++) {
    record = record[keys[i]] || (i === keys.length - 1 ? defaultValue : {});
  }
  return record || defaultValue;
}

/**
 * 数组转对象
 * @param rs 集合
 * @param key 需要转换目标key的名称
 * @param render 渲染函数
 * @returns 转换后的对象
 */
export function arrayToObject(rs: any[] = [], key: string | IFunction, render?: IFunction): IObject {
  const o: IObject = {};
  rs.forEach((x) => {
    o[typeof key === 'function' ? key(x) : x[key]] = render ? render(x) : x;
  });
  return o;
}

/**
 * 数组转换格式
 * @param rs 数组
 * @param render 渲染函数
 * @returns 转换后的数组
 */
export function arrayToKeyValueArray(rs: any[] = [], render?: IFunction): any[] {
  return rs.map(x => (render ? render(x) : typeof x === 'object' ? x : { label: x, value: x }));
}

/**
 * 是否只null和undefined值
 * @param vl
 * @returns
 */
export function isNullOrUndefined(vl: unknown): boolean {
  return vl === null || typeof vl === 'undefined';
}

/**
 * 是否外链
 * @param path
 * @returns
 */
export function isExternalLink(path: string): boolean {
  return /^(https?:|\/\/|mailto:|tel:|^\{\{\s?ApiUrl\s?\}\})/.test(path);
}

/**
 * 复制
 * @param value
 */
export function copyToClipboard(value: string): void {
  const transfer = document.createElement('textarea');
  document.body.appendChild(transfer);
  transfer.value = value;
  transfer.focus();
  transfer.select();
  if (document.execCommand('copy')) {
    document.execCommand('copy');
  }
  transfer.blur();
  document.body.removeChild(transfer);
}

/**
 * 检查是否有权限
 * @param permission
 * @param key
 * @returns
 */
export function checkPermission(permission: string[], key: string): boolean {
  return permission.includes(key);
}

/**
 * 获取uuid
 * @returns UUID字符串
 */
export function getUuid(): string {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0;
    const v = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

/**
 * 邮箱验证
 * @param s 邮箱字符串
 * @returns 是否为有效邮箱
 */
export function isEmail(s: string): boolean {
  return /^[\w.-]+@[\w-]+(?:\.[\w-]{2,3}){1,2}$/.test(s);
}

/**
 * 手机号码验证
 * @param s 手机号字符串
 * @returns 是否为有效手机号
 */
export function isMobile(s: string): boolean {
  return /^1\d{10}$/.test(s);
}

/**
 * 电话号码验证
 * @param s 电话号字符串
 * @returns 是否为有效电话号
 */
export function isPhone(s: string): boolean {
  return /^(?:\d{3,4}-)?\d{7,8}$/.test(s);
}

/**
 * URL地址验证
 * @param s URL字符串
 * @returns 是否为有效URL
 */
export function isURL(s: string): boolean {
  return /^https?:\/\/.+/.test(s);
}

/**
 * 正整数验证
 * @param s 数字字符串
 * @returns 是否为正整数
 */
export function isNumber(s: string): boolean {
  return /^\+?[1-9]\d*$/.test(s);
}

/**
 * 获取字典数据列表
 * @param list 字典列表
 * @param dictType 字典类型
 * @returns 字典数据列表
 */
export function getDictDataList(list: IObject[], dictType?: string): IObject[] {
  const type = list.find((element: IObject) => element.dictType === dictType);
  if (type) {
    return type.dataList;
  }
  else {
    return [];
  }
}

/**
 * 获取字典名称
 * @param list 字典列表
 * @param dictType 字典类型
 * @param dictValue 字典值
 * @returns 字典标签
 */
export function getDictLabel(list: IObject[], dictType: string, dictValue: number): string | number {
  const type = list.find((element: IObject) => element.dictType === dictType);
  if (type) {
    const val = type.dataList.find((element: IObject) => element.dictValue === `${dictValue}`);
    if (val) {
      return val.dictLabel;
    }
    else {
      return dictValue;
    }
  }
  else {
    return dictValue;
  }
}

/**
 * 获取svg图标(id)列表
 * @returns 图标ID列表
 */
export function getIconList(): string[] {
  const rs: string[] = [];
  const list = document.querySelectorAll('svg symbol');
  for (let i = 0; i < list.length; i++) {
    rs.push(list[i].id);
  }
  return rs;
}

/**
 * 树形数据转换
 * @param data 数据数组
 * @param id ID字段名
 * @param pid 父ID字段名
 * @returns 树形结构数据
 */
export function treeDataTranslate(data: IObject[], id?: string, pid?: string): IObject[] {
  const res: IObject[] = [];
  const temp: IObject = {};
  id = id || 'id';
  pid = pid || 'pid';
  for (let i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i];
  }
  for (let k = 0; k < data.length; k++) {
    if (!temp[data[k][pid]] || data[k][id] === data[k][pid]) {
      res.push(data[k]);
      continue;
    }
    if (!temp[data[k][pid]].children) {
      temp[data[k][pid]].children = [];
    }
    temp[data[k][pid]].children.push(data[k]);
    data[k]._level = (temp[data[k][pid]]._level || 0) + 1;
  }
  return res;
}
